home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / network / ncsasock / tcpglue.c < prev    next >
Text File  |  1996-07-05  |  11KB  |  527 lines

  1. /*
  2.  * BSD-style socket emulation library for the Mac
  3.  * Original author: Tom Milligan
  4.  * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
  5.  *
  6.  * This source file is placed in the public domian.
  7.  * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
  8.  *
  9.  *      National Center for Supercomputing Applications
  10.  *      152 Computing Applications Building
  11.  *      605 E. Springfield Ave.
  12.  *      Champaign, IL  61820
  13.  */
  14.  
  15. /*
  16.  *    Glue routines to call the MacTCP drivers
  17.  */
  18.  
  19. #ifdef USEDUMP
  20. # pragma load "socket.dump"
  21.  
  22. #else
  23. # include <Memory.h>
  24. # include <Files.h>
  25. # include <Errors.h>
  26.  
  27. # include <s_types.h>
  28. # include <neti_in.h>
  29.  
  30. # include "sock_str.h"
  31.  
  32. # include "sock_int.h"
  33.  
  34. #endif
  35.  
  36. #include <Devices.h>
  37.  
  38. static short driver = 0;
  39.  
  40. /*
  41.  * Hack fix for MacTCP 1.0.X bug
  42.  */
  43.  
  44. #ifdef COMP_CODEWAR
  45. #include <LowMem.h>
  46. #define    ReturnA5(x) LMGetCurrentA5(x)
  47. #else
  48. pascal char *ReturnA5(void) = {0x2E8D};
  49. #endif
  50.  
  51. OSErr xOpenDriver() 
  52.     if (driver == 0) 
  53.     { 
  54.         ParamBlockRec pb; 
  55.         OSErr io; 
  56.         
  57.         pb.ioParam.ioCompletion = 0L; 
  58.         pb.ioParam.ioNamePtr = "\p.IPP"; 
  59.         pb.ioParam.ioPermssn = fsCurPerm; 
  60.         io = PBOpen(&pb,false); 
  61.         if (io != noErr) 
  62.             return(io); 
  63.         driver = pb.ioParam.ioRefNum; 
  64.     }
  65.     return noErr;
  66. }
  67.  
  68.  
  69. /*
  70.  * create a TCP stream
  71.  */
  72. OSErr xTCPCreate(
  73.     int buflen,
  74.     TCPNotifyProc notify,
  75.     TCPiopb *pb)
  76. {    
  77.     TCPNotifyUPP upp= NewTCPNotifyProc(notify);
  78.     
  79.     pb->ioCRefNum = driver;
  80.     pb->csCode = TCPCreate;
  81.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  82.     pb->csParam.create.rcvBuffLen = buflen;
  83.     pb->csParam.create.notifyProc = (TCPNotifyProc) upp;
  84.     return (xPBControlSync(pb));
  85. }
  86.  
  87. /*
  88.  * start listening for a TCP connection
  89.  */
  90. OSErr xTCPPassiveOpen( 
  91.     TCPiopb *pb, 
  92.     short port,
  93.     TCPIOCompletionProc completion)
  94. {
  95.     if (driver == 0)
  96.         return(invalidStreamPtr);
  97.  
  98.     pb->ioCRefNum = driver;
  99.     pb->csCode = TCPPassiveOpen;
  100.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  101.     pb->csParam.open.ulpTimeoutValue = 255 /* was 255 seconds */;
  102.     pb->csParam.open.ulpTimeoutAction = 0 /* 1:abort 0:report */;
  103.     pb->csParam.open.commandTimeoutValue = 0 /* infinity */;
  104.     pb->csParam.open.remoteHost = 0;
  105.     pb->csParam.open.remotePort = 0;
  106.     pb->csParam.open.localHost = 0;
  107.     pb->csParam.open.localPort = port;
  108.     pb->csParam.open.dontFrag = 0;
  109.     pb->csParam.open.timeToLive = 0;
  110.     pb->csParam.open.security = 0;
  111.     pb->csParam.open.optionCnt = 0;
  112.     return (xPBControl(pb,completion));
  113. }
  114.  
  115. /*
  116.  * connect to a remote TCP
  117.  */
  118. OSErr xTCPActiveOpen( 
  119.     TCPiopb *pb, 
  120.     short port,
  121.     long rhost,
  122.     short rport,
  123.     TCPIOCompletionProc completion)
  124. {
  125.     if (driver == 0)
  126.         return(invalidStreamPtr);
  127.  
  128.     pb->ioCRefNum = driver;
  129.     pb->csCode = TCPActiveOpen;
  130.     pb->csParam.open.validityFlags = timeoutValue | timeoutAction;
  131.     pb->csParam.open.ulpTimeoutValue = 20 /* seconds, was 60 */;
  132.     pb->csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  133.     pb->csParam.open.commandTimeoutValue = 0;
  134.     pb->csParam.open.remoteHost = rhost;
  135.     pb->csParam.open.remotePort = rport;
  136.     pb->csParam.open.localHost = 0;
  137.     pb->csParam.open.localPort = port;
  138.     pb->csParam.open.dontFrag = 0;
  139.     pb->csParam.open.timeToLive = 0;
  140.     pb->csParam.open.security = 0;
  141.     pb->csParam.open.optionCnt = 0;
  142.     return (xPBControl(pb,completion));
  143. }
  144.  
  145. OSErr xTCPNoCopyRcv( 
  146.     TCPiopb *pb,
  147.     rdsEntry *rds, 
  148.     int rdslen,
  149.     int    timeout,
  150.     TCPIOCompletionProc completion)
  151. {
  152.     
  153.     if (driver == 0)
  154.         return(invalidStreamPtr);
  155.     
  156.     pb->ioCRefNum = driver;
  157.     pb->csCode = TCPNoCopyRcv;
  158.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  159.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  160.     pb->csParam.receive.rdsLength = rdslen;
  161.     return (xPBControl(pb,completion));
  162. }
  163.  
  164. OSErr xTCPBufReturn(TCPiopb *pb,rdsEntry *rds,TCPIOCompletionProc completion)
  165.     {
  166.     pb->ioCRefNum = driver;
  167.     pb->csCode = TCPRcvBfrReturn;
  168.     pb->csParam.receive.rdsPtr = (Ptr)rds;
  169.     
  170.     return (xPBControl(pb,completion));
  171.     }
  172.     
  173. /*
  174.  * send data
  175.  */
  176. OSErr xTCPSend( 
  177.     TCPiopb *pb,
  178.     wdsEntry *wds, 
  179.     Boolean push,
  180.     Boolean urgent,
  181.     TCPIOCompletionProc completion)
  182. {
  183.     if (driver == 0)
  184.         return invalidStreamPtr;
  185.     
  186.     pb->ioCRefNum = driver;
  187.     pb->csCode = TCPSend;
  188.     pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
  189.     pb->csParam.send.ulpTimeoutValue = 20 /* seconds, 60 */;
  190.     pb->csParam.send.ulpTimeoutAction = 0 /* 0:abort 1:report */;
  191.     pb->csParam.send.pushFlag = push;
  192.     pb->csParam.send.urgentFlag = urgent;
  193.     pb->csParam.send.wdsPtr = (Ptr)wds;
  194.     return (xPBControl(pb,completion));
  195. }
  196.  
  197.  
  198. /*
  199.  * close a connection
  200.  */
  201. OSErr xTCPClose(TCPiopb *pb,TCPIOCompletionProc completion) 
  202. {
  203.     if (driver == 0)
  204.         return(invalidStreamPtr);
  205.     
  206.     pb->ioCRefNum = driver;
  207.     pb->csCode = TCPClose;
  208.     pb->csParam.close.validityFlags = timeoutValue | timeoutAction;
  209.     pb->csParam.close.ulpTimeoutValue = 20 /* seconds, 60 */;
  210.     pb->csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
  211.     return (xPBControl(pb,completion));
  212. }
  213.  
  214. /*
  215.  * abort a connection
  216.  */
  217. OSErr xTCPAbort(TCPiopb *pb) 
  218. {
  219.     if (driver == 0)
  220.         return(invalidStreamPtr);
  221.     
  222.     pb->ioCRefNum = driver;
  223.     pb->csCode = TCPAbort;
  224.     return (xPBControlSync(pb));
  225. }
  226.  
  227. /*
  228.  * close down a TCP stream (aborting a connection, if necessary)
  229.  */
  230. OSErr xTCPRelease( 
  231.     TCPiopb *pb)
  232. {
  233.     OSErr io;
  234.     
  235.     if (driver == 0)
  236.         return(invalidStreamPtr);
  237.     
  238.     pb->ioCRefNum = driver;
  239.     pb->csCode = TCPRelease;
  240.     io = xPBControlSync(pb);
  241.     if (io == noErr)
  242.         DisposPtr(pb->csParam.create.rcvBuff); /* there is no release pb */
  243.     return(io);
  244. }
  245.  
  246. int
  247. xTCPBytesUnread(SocketPtr sp) 
  248. {
  249.     TCPiopb    *pb;
  250.     OSErr io;
  251.     
  252.     if (!(pb = (TCPiopb    *)sock_fetch_pb(sp)))
  253.         return -1;        /* panic */
  254.     
  255.     if (driver == 0)
  256.         return(-1);
  257.     
  258.     pb->ioCRefNum = driver;
  259.     pb->csCode = TCPStatus;
  260.     io = xPBControlSync(pb);
  261.     if (io != noErr)
  262.         return(-1);
  263.     return(pb->csParam.status.amtUnreadData);
  264. }
  265.  
  266. int
  267. xTCPBytesWriteable(SocketPtr sp)
  268.     {
  269.     TCPiopb *pb;
  270.     OSErr    io;
  271.     long    amount;
  272.     
  273.     if (!(pb = (TCPiopb    *)sock_fetch_pb(sp)))
  274.         return -1;        /* panic */
  275.     
  276.     if (driver == 0)
  277.         return(-1);
  278.     
  279.     pb->ioCRefNum = driver;
  280.     pb->csCode = TCPStatus;
  281.     io = xPBControlSync(pb);
  282.     if (io != noErr)
  283.         return(-1);
  284.     amount = pb->csParam.status.sendWindow-pb->csParam.status.amtUnackedData;
  285.     if (amount < 0)
  286.         amount = 0;
  287.     return amount;
  288.     }
  289.     
  290. int xTCPWriteBytesLeft(SocketPtr sp)
  291.     {
  292.     TCPiopb *pb;
  293.     OSErr    io;
  294.     
  295.     if (!(pb = (TCPiopb    *)sock_fetch_pb(sp)))
  296.         return -1;        /* panic */
  297.     
  298.     if (driver == 0)
  299.         return(-1);
  300.     
  301.     pb->ioCRefNum = driver;
  302.     pb->csCode = TCPStatus;
  303.     io = xPBControlSync(pb);
  304.     if (io != noErr)
  305.         return(-1);
  306.     return (pb->csParam.status.amtUnackedData);
  307.     }
  308.  
  309. int xTCPState(TCPiopb *pb)
  310.     {
  311.     OSErr io;
  312.     
  313.     if (driver == 0)
  314.         return(-1);
  315.     
  316.     pb->ioCRefNum = driver;
  317.     pb->csCode = TCPStatus;
  318.     io = xPBControlSync(pb);
  319.     if (io != noErr)
  320.         return(-1);
  321.     return(pb->csParam.status.connectionState);
  322.     }
  323.  
  324.  
  325. /*
  326.  * create a UDP stream, hook it to a socket.
  327.  */
  328. OSErr xUDPCreate(SocketPtr sp,int buflen,ip_port port)
  329.     {    
  330.     UDPiopb *pb;
  331.     OSErr   io;
  332.     
  333.     if ( !(pb = (UDPiopb *)sock_fetch_pb(sp) ) )
  334.         return -1;
  335.     
  336.     pb->ioCRefNum = driver;
  337.     pb->csCode = UDPCreate;
  338.     pb->csParam.create.rcvBuff = (char *)NewPtr(buflen);
  339.     pb->csParam.create.rcvBuffLen = buflen;
  340.     pb->csParam.create.notifyProc = NULL;
  341.     pb->csParam.create.localPort = port;
  342.     if ( (io = xPBControlSync( (TCPiopb *)pb ) ) != noErr)
  343.         return io;
  344.         
  345.     sp->stream = pb->udpStream;
  346.     sp->sa.sin_port = pb->csParam.create.localPort;
  347.     return noErr;
  348.     }
  349.  
  350. /*
  351.  * ask for incoming data
  352.  */
  353. OSErr xUDPRead(SocketPtr sp,UDPIOCompletionProc completion) 
  354.     {
  355.     UDPiopb *pb;
  356.     
  357.     if ( !(pb = (UDPiopb *)sock_fetch_pb(sp) ))
  358.         return -1;
  359.     
  360.     if (driver == 0)
  361.         return(invalidStreamPtr);
  362.     
  363.     pb->ioCRefNum = driver;
  364.     pb->csCode = UDPRead;
  365.     pb->csParam.receive.timeOut = 0 /* infinity */;
  366.     pb->csParam.receive.secondTimeStamp = 0/* must be zero */;
  367.     return (xPBControl ( (TCPiopb *)pb, (TCPIOCompletionProc)completion ));
  368.     }
  369.  
  370. OSErr xUDPBfrReturn(SocketPtr sp) 
  371.     {
  372.     UDPiopb *pb;
  373.  
  374.     if ( !(pb = (UDPiopb *)sock_fetch_pb(sp) ))
  375.         return -1;
  376.  
  377.     if (driver == 0)
  378.         return(invalidStreamPtr);
  379.     
  380.     pb->ioCRefNum = driver;
  381.     pb->csCode = UDPBfrReturn;
  382.     pb->csParam.receive.rcvBuff = sp->recvBuf;
  383.     sp->recvBuf = 0;
  384.     sp->recvd   = 0;
  385.     return ( xPBControl( (TCPiopb *)pb,(TCPIOCompletionProc)-1 ) );
  386.     }
  387.  
  388. /*
  389.  * send data
  390.  */
  391. OSErr xUDPWrite(SocketPtr sp,ip_addr host,ip_port port,miniwds *wds,
  392.         UDPIOCompletionProc completion) 
  393.     {
  394.     UDPiopb    *pb;
  395.     
  396.     if ( !(pb = (UDPiopb *)sock_fetch_pb(sp) ))
  397.         return -1;
  398.         
  399.     if (driver == 0)
  400.         return(invalidStreamPtr);
  401.     
  402.     pb->ioCRefNum = driver;
  403.     pb->csCode = UDPWrite;
  404.     pb->csParam.send.remoteHost = host;
  405.     pb->csParam.send.remotePort = port;
  406.     pb->csParam.send.wdsPtr = (Ptr)wds;
  407.     pb->csParam.send.checkSum = true;
  408.     pb->csParam.send.sendLength = 0/* must be zero */;
  409.     return (xPBControl( (TCPiopb *)pb, (TCPIOCompletionProc)completion));
  410.     }
  411.  
  412. /*
  413.  * close down a UDP stream (aborting a read, if necessary)
  414.  */
  415. OSErr xUDPRelease(SocketPtr sp) {
  416.     UDPiopb *pb;
  417.     OSErr io;
  418.  
  419.     if ( !(pb = (UDPiopb *)sock_fetch_pb(sp) ))
  420.         return -1;
  421.     
  422.     if (driver == 0)
  423.         return(invalidStreamPtr);
  424.     
  425.     pb->ioCRefNum = driver;
  426.     pb->csCode = UDPRelease;
  427.     io = xPBControlSync( (TCPiopb *)pb );
  428.     if (io == noErr) {
  429.         DisposPtr(pb->csParam.create.rcvBuff);
  430.         }
  431.     return(io);
  432.     }
  433.  
  434. ip_addr xIPAddr(void) 
  435. {
  436.     struct GetAddrParamBlock pbr; /* was IPParamBlock pbr; */
  437.     OSErr io;
  438.     
  439.     pbr.ioCRefNum = driver;
  440.     pbr.csCode = ipctlGetAddr;
  441.     io = xPBControlSync( (TCPiopb *)&pbr );
  442.     if (io != noErr)
  443.         return(0);
  444.     return(pbr.ourAddress);/*IPEchoPB.dest ?? */
  445. }
  446.  
  447. long xNetMask() 
  448. {
  449.     struct GetAddrParamBlock pbr; /* was IPParamBlock pbr; */
  450.     OSErr io;
  451.     
  452.     pbr.ioCRefNum = driver;
  453.     pbr.csCode = ipctlGetAddr;
  454.     io = xPBControlSync( (TCPiopb *)&pbr);
  455.     if (io != noErr)
  456.         return(0);
  457.     return(pbr.ourNetMask);  
  458. }
  459.  
  460. unsigned short xMaxMTU()
  461. {
  462.     struct UDPiopb pbr;
  463.     OSErr io;
  464.     
  465.     pbr.ioCRefNum = driver;
  466.     pbr.csCode = UDPMaxMTUSize;
  467.     pbr.csParam.mtu.remoteHost = xIPAddr();
  468.     io = xPBControlSync( (TCPiopb *)&pbr );
  469.     if (io != noErr)
  470.         return(0);
  471.     return(pbr.csParam.mtu.mtuSize);
  472. }
  473.  
  474. OSErr xPBControlSync(TCPiopb *pb) 
  475.     (pb)->ioCompletion = 0L; 
  476.     return PBControl((ParmBlkPtr)(pb),false); 
  477. }
  478.  
  479. #ifndef COMP_CODEWAR
  480. #pragma segment SOCK_RESIDENT
  481. #endif
  482.  
  483. OSErr xTCPRcv( 
  484.     TCPiopb *pb,
  485.     Ptr buf, 
  486.     int buflen,
  487.     int    timeout,
  488.     TCPIOCompletionProc completion)
  489. {
  490.     
  491.     if (driver == 0)
  492.         return(invalidStreamPtr);
  493.     
  494.     pb->ioCRefNum = driver;
  495.     pb->csCode = TCPRcv;
  496.     pb->csParam.receive.commandTimeoutValue = timeout; /* seconds, 0 = blocking */
  497.     pb->csParam.receive.rcvBuff = buf;
  498.     pb->csParam.receive.rcvBuffLen = buflen;
  499.     return (xPBControl(pb,completion));
  500. }
  501.  
  502.  
  503. OSErr xPBControl(TCPiopb *pb,TCPIOCompletionProc completion) 
  504.     pb->ioNamePtr = ReturnA5();
  505.     
  506.     if (completion == 0L) 
  507.     { 
  508.         (pb)->ioCompletion = 0L; 
  509.         return(PBControl((ParmBlkPtr)(pb),false));        /* sync */
  510.     } 
  511.     else if (completion == (TCPIOCompletionProc)-1L) 
  512.     { 
  513.         (pb)->ioCompletion = 0L; 
  514.         return(PBControl((ParmBlkPtr)(pb),true));        /* async */
  515.     } 
  516.     else 
  517.     {  
  518.         TCPIOCompletionUPP upp= NewTCPIOCompletionProc(completion);
  519.         (pb)->ioCompletion = (TCPIOCompletionProc) upp; 
  520.         return(PBControl((ParmBlkPtr)(pb),true));        /* async */
  521.     } 
  522. }
  523.  
  524.